using MicroMsg.Common.Utils;
using MicroMsg.Protocol;
using System;
using System.Data.Linq;
namespace MicroMsg.Storage
{
	public class StorageDB
	{
		private const string TAG = "StorageDB";
		private const string db_data_file = "/database.sdf";
		private const string db_schema_file = "/db_schema.xml";
		private static string db_path;
		public static string db_setting;
		private static StorageDBSchema db_schema;
		public static LinqDB db_handle;
		public static bool bInit = false;
		public static StorageMapping default_mapping = new StorageMapping();
		private static StorageDBSchema getDBSchema(bool compatibleOld = true)
		{
			StorageDBSchema storageDBSchema = StorageXml.loadObject<StorageDBSchema>(StorageDB.db_path + "/db_schema.xml");
			if (storageDBSchema != null)
			{
				return storageDBSchema;
			}
			return StorageUpdater.schema_patch_getSchema10001();
		}
		public static void saveDBSchema(StorageDBSchema storageDBSchema_0)
		{
			StorageXml.saveObject<StorageDBSchema>(storageDBSchema_0, StorageDB.db_path + "/db_schema.xml");
		}
		public static DataContext init(string path)
		{
			DataContext result;
			try
			{
				if (StorageDB.bInit)
				{
					DebugEx.debugBreak();
				}
				StorageDB.bInit = true;
				StorageDB.db_path = path;
				StorageDB.db_setting = "Data Source=isostore:/" + StorageDB.db_path + "/database.sdf; max database size = 64 ";
				StorageDB.db_handle = new LinqDB();
				if (StorageDB.db_handle.DatabaseExists())
				{
					Log.smethod_5("StorageDB", "open database  " + path + ",build time=" + AppCompileDate.CreateDate);
					StorageDB.db_schema = StorageDB.getDBSchema(true);
					StoragePatch.updateSchemaByVersion(StorageDB.db_schema);
					if (StorageUpdater.needUpdateSchema(typeof(LinqDB), StorageDB.db_schema))
					{
						using (LinqDB linqDB = new LinqDB())
						{
							if (!StorageUpdater.updateSchema(typeof(LinqDB), StorageDB.db_schema, linqDB))
							{
								DebugEx.debugBreak();
								throw new FormatException("db update schema error");
							}
							StorageDB.saveDBSchema(StorageDB.db_schema);
						}
					}
					if (StorageDB.db_schema.version != ConstantsProtocol.CLIENT_VERSION)
					{
						StorageDB.db_schema.version = ConstantsProtocol.CLIENT_VERSION;
						StorageDB.saveDBSchema(StorageDB.db_schema);
					}
					StorageDB.db_handle.set_ObjectTrackingEnabled(false);
					result = StorageDB.db_handle;
				}
				else
				{
					Log.smethod_5("StorageDB", "create database  " + path + ",build time=" + AppCompileDate.CreateDate);
					StorageDB.db_handle.CreateDatabase();
					StorageDB.db_handle.SubmitChanges();
					StorageDB.db_handle.Dispose();
					StorageDB.db_schema = StorageUpdater.getSchemaFromType(typeof(LinqDB));
					StorageDB.saveDBSchema(StorageDB.db_schema);
					StorageDB.db_handle = new LinqDB();
					StorageDB.db_handle.set_ObjectTrackingEnabled(false);
					result = StorageDB.db_handle;
				}
			}
			catch (Exception ex)
			{
				Log.smethod_1("StorageDB", "StorageDB database init fail " + ex);
				throw;
			}
			return result;
		}
		public static void uninit()
		{
			if (!StorageDB.bInit)
			{
				return;
			}
			StorageDB.db_handle.Dispose();
			StorageDB.db_handle = null;
			StorageDB.db_path = null;
			StorageDB.db_setting = null;
			StorageDB.db_schema = null;
			StorageDB.bInit = false;
		}
		public static void delete()
		{
			if (!StorageDB.bInit)
			{
				return;
			}
			StorageDB.db_handle.DeleteDatabase();
		}
		public static bool isTableExist(Type tabType)
		{
			return tabType != null && StorageDB.isTableExist(tabType.get_Name());
		}
		public static bool isTableExist(string tabName)
		{
			if (!StorageDB.bInit)
			{
				DebugEx.debugBreak();
				return false;
			}
			return StorageDB.db_schema.tables.ContainsKey(tabName);
		}
		public static bool addTable(Type tabType)
		{
			if (tabType == null || !StorageDB.bInit)
			{
				Log.smethod_1("StorageDB", "database unready ");
				DebugEx.debugBreak();
				return false;
			}
			if (StorageDB.isTableExist(tabType.get_Name()))
			{
				return true;
			}
			using (DataContext dataContext = StorageDB.default_mapping.newDB())
			{
				StorageUpdater.addTable(dataContext, tabType, StorageDB.db_schema);
			}
			StorageDB.saveDBSchema(StorageDB.db_schema);
			return true;
		}
		public static bool isColumnChange(Type tabType)
		{
			if (StorageDB.bInit && tabType != null)
			{
				return null != StorageUpdater.getAddColumnList(tabType, StorageDB.db_schema);
			}
			Log.smethod_1("StorageDB", "database unready ");
			DebugEx.debugBreak();
			return false;
		}
		public static bool syncColumn(Type tabType)
		{
			if (tabType == null || !StorageDB.bInit)
			{
				Log.smethod_1("StorageDB", "database unready ");
				DebugEx.debugBreak();
				return false;
			}
			if (!StorageDB.isColumnChange(tabType))
			{
				return false;
			}
			StorageUpdater.syncColumn(StorageDB.db_handle, tabType, StorageDB.db_schema);
			StorageDB.saveDBSchema(StorageDB.db_schema);
			return true;
		}
	}
}
